package roborally.model.executables;

import be.kuleuven.cs.som.annotate.*;
import roborally.model.Program;
import roborally.model.Robot;
/**
 * A class representing a component that is executable in our selfdefined robot-programminglanguage and 
 * execution of this command results in a change of state of the associated robot.
 */
public abstract class RobotCommand extends Executable {
	
	/**
	 * The associated robot.
	 */
	private final Robot robot; 
	@Basic @Immutable
	public final Robot getRobot(){ return this.robot; }
	
	private final Program program; 
	@Basic @Immutable
	public final Program getProgram(){ return this.program; }
	/**
	 * Consturcts a RobotCommand Executable with an associated robot and program.
	 * @post The parameters are assigned to their instance variables.
	 */
	@Model
	protected RobotCommand(Robot robot, Program program){
		this.robot = robot;
		this.program = program;
	}
	
	/**
	 * Executes this command on its robot.
	 */
	public abstract void executeCommand(); //implement the execution in this method for every specific RobotCommand
	
	@Override
	public boolean executeNextRobotCommand(RobotCommand lastExecutedRobotCommand){
		if(this == lastExecutedRobotCommand) return false;
		executeCommand();
		program.setLastExecutedRobotCommand(this);
		return true;
	}

	@Override
	public boolean contains(Executable other){
		return this == other;
	}
	
}
